/*
 * com.c
 *  该任务用于WIFI通信
 *  Created on: 2025.4.3
 *      Author: TracyHenry
 */
/*ESP8266 WIFI Station 代码*/
#include "com.h"
#include <stdio.h>
#include "timemanage.h"
#include "motorcontrol.h"
#include "timelist.h"
#include "flash.h"
#include "tim.h"
#include "w25q16.h"
#include "crc.h"
#include "taskMotor.h"
#include <string.h>
#include "user_config.h"
#include "taskStorage.h"

#define UART_SEND_MAX 100

uint8_t rxBuffer[RX_BUFFER_SIZE];
volatile uint8_t rxIndex = 0;
volatile uint8_t dataReceived = 0;

extern xQueueHandle taskStorageQueue;

// Modbus相关定义
#define MODBUS_SLAVE_ADDRESS 0x01
#define MODBUS_READ_HOLDING_REGISTERS 0x03

// Modbus请求帧结构
typedef struct {
    uint8_t slaveAddress;
    uint8_t functionCode;
    uint16_t startAddress;
    uint16_t numRegisters;
    uint16_t crc;
} ModbusRequest;

typedef struct {
    uint8_t wifiStatus;
    uint8_t serverStatus;
} WifiInfo;

WifiInfo wifiInfo;

uint8_t flagFirmwareUpdate = 0;
//uart缓冲区全局变量，用于存放收到的数据

void takeTask(void);

/******************************************************************************
 * FunctionName : taskInit
 * Description  : 任务级初始化
 * Parameters   : void
 * Returns      : pdFAIL or pdPASS 代表是否停止任务成功
*******************************************************************************/
void taskComInit(void)
{
    // 在main函数中初始化UART和DMA
    HAL_UART_Receive_DMA(&huart4, rxBuffer, RX_BUFFER_SIZE);
    
    // 启用空闲中断
    __HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);

}


/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the myTask02 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void comTask(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  while (1) 
	{
        if (dataReceived) 
		{				
            // if(isCRCLegal() != pdPASS)
            // {
            //     printf("CRC is illegal\n");
                
            // }
						// else
						// {
			analysisData();
						// }
            // 处理接收到的数据
            // 例如，将数据打印出来
            HAL_UART_Transmit(&huart3, rxBuffer, rxIndex, HAL_MAX_DELAY);
            // 重置接收状态
            rxIndex = 0;
            dataReceived = 0;
            // 重新启动DMA接收
            HAL_UART_Receive_DMA(&huart4, rxBuffer, RX_BUFFER_SIZE);
        }
     }
  /* USER CODE END StartTask02 */
}

 /******************************************************************************
 * FunctionName : isCRCLegal
 * Description  : 判断crc是否合法
 * Parameters   : void
 * Returns      : portBASE_TYPE
*******************************************************************************/
portBASE_TYPE isCRCLegal(void)
{
	
	  if(rxIndex < 4)
		{
		  return pdFAIL;
		}
    uint16_t crc = (((uint16_t)rxBuffer[rxIndex - 2]) << 8) | ((uint16_t)rxBuffer[rxIndex - 1]);

    uint16_t crc_calc = CalculateCRC16(rxBuffer, rxIndex-2);


    if (crc == crc_calc)
    {
      return pdPASS;
    }
    else
    {
      return pdFAIL;
    }
}

void analysisData(void)
{
    switch (rxBuffer[0])
    {
    case UDP_Set_Motor_Start_Stop:
        /* code */
        setRelay();
        break;
    case UDP_Set_Device_Time:
        /* code */
        setTime();
        break;
    case UDP_Set_Time_Tasks:
        /* code */
        analysisTimeList();
        break;
    case UDP_Get_Motor_Status:
        getRelayStatus();
        break;
    case UDP_Get_Device_Time:
        //takeTask();
        // if (taskStorageSemaphore != NULL) {
        // xSemaphoreGive(taskStorageSemaphore); // 初始状态为可触发
        // }
        getRTCTime();
        //testFlash();
        break;
    case UDP_Get_Time_Tasks:
         //eraseAll();
         break;
    case UDP_Set_Motor_Speed:
        outPutPWM();
        break;
	case UDP_Set_Motor_Direction:
        setRelayDirection();
		break;
    case MQTT_Set_Motor_Param:
		controlTask();
        break;
    case MQTT_Set_Feed_Base_Param:
    case MQTT_Set_Operation_Mode:
    case MQTT_Set_Feed_Mode:
    case MQTT_Set_LiveStocksFeed_Mode:
    case MQTT_Set_Time_Mode:
    case MQTT_Set_LiveStockWaterOrder_Mode:
    case MQTT_Set_IdleWater_Param:
    case MQTT_Set_CycleFeedTime_Param:
        setParamByMqtt();
        break;
    case MQTT_Get_Feed_Base_Param:
    case MQTT_Get_Operation_Mode:
    case MQTT_Get_Feed_Mode:
    case MQTT_Get_LiveStocksFeed_Mode:
    case MQTT_Get_Time_Mode:
    case MQTT_Get_LiveStockWaterOrder_Mode:
    case MQTT_Get_IdleWater_Param:
    case MQTT_Get_CycleFeedTime_Param:
    case MQTT_Get_Motor_Status:
    case MQTT_Get_SoftWare_Version:
        sendByMqtt(rxBuffer[0]);
        break;    
    default:
        break;
    }
}

/******************************************************************************
 * FunctionName : HAL_UART_RxCpltCallback
* Description  : UART 接收完成回调函数
 * Parameters   : void
 * Returns      : void
*******************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

}


/******************************************************************************
 * FunctionName : setRelay
 * Description  : com接收设置电机开关是否打开（无刷电机的刹车线）
 * Parameters   : void
 * Returns      : void
*******************************************************************************/
void setRelay(void) 
{

    switch (rxBuffer[1])
    {
    case 1:
        /* code */
        flagMotorControl1Update = 1;
        motorControl1Action = rxBuffer[2];
        break;
    case 2:
        /* code */
        flagMotorControl2Update = 1;
        motorControl2Action = rxBuffer[2];
        break;
    case 3:
        /* code */
        flagMotorControl3Update = 1;
        motorControl3Action = rxBuffer[2];
        break;    
    default:
        break;
    }
}

/******************************************************************************
 * FunctionName : setTime
 * Description  : com接收设置指令
 * Parameters   : void
 * Returns      : void
*******************************************************************************/
void setTime(void) 
{
	
	 if(isCRCLegal() != pdPASS)
	 {
			 printf("CRC is illegal\n");
			 return;
	 }

    now_time.year = rxBuffer[1];
    now_time.month = rxBuffer[2];
    now_time.date = rxBuffer[3];
    now_time.hour = rxBuffer[4];
    now_time.minute = rxBuffer[5];
    now_time.second = rxBuffer[6];
    now_time.day = rxBuffer[7];
    DS1307_SetTime(now_time.second, now_time.minute, now_time.hour, now_time.date, now_time.month, now_time.year, now_time.day);
}

/******************************************************************************
 * FunctionName : analysisTimeList
 * Description  : com解析时间表数据
 * Parameters   : void
 * Returns      : void
*******************************************************************************/
extern uint8_t flag_set_timelist;
void analysisTimeList(void)
{
    QueueSetParamEvent e;
    if(flag_set_timelist != 0)
    {
        printf("time list setting!!\r\n");
        return;
    }
    uint8_t i,speedA,speedB;
    uint16_t year_buf, month_buf, date_buf, hour_buf, minute_buf, duration_buf;
    uint8_t timesize = rxBuffer[1];
    freeTimeTable(timeTable);
    for (i = 0; i < timesize; i++)
    {
      year_buf = rxBuffer[9*i+2];
      month_buf = rxBuffer[9*i+3];
      date_buf = rxBuffer[9*i+4];
      hour_buf = rxBuffer[9*i+5];
      minute_buf = rxBuffer[9*i+6];
      duration_buf = (((uint16_t)rxBuffer[9*i+7]) << 8) | ((uint16_t)rxBuffer[9*i+8]);
      speedA = rxBuffer[9*i+9];
      speedB = rxBuffer[9*i+10];
      insertNode(&timeTable, createNode(year_buf, month_buf, date_buf, hour_buf, minute_buf, duration_buf, speedA, speedB));
    }

    if (taskStorageQueue != NULL) {
          e.event = 1;
         xQueueSend(taskStorageQueue, &e,0); // 初始状态为可触发 触发存储任务
    }
}


//uint8_t FlashWBuff [255];
//uint8_t FlashRBuff [255];
uint8_t count = 0;
void testFlash(void)
{
        // 要写入的数据
	//uint8_t i;
	//TimeTableNode FlashTest;
	//uint8_t read_data[16];
    DEVICE_INFO deviceinfo;
    DEVICE_INFO deviceinfo_read;
  //  uint16_t i;

    // for (i = 0; i < 128; i++)
    // {
    //     FlashTest[i] = i;
    // }
    count++;
//  /* USER CODE BEGIN SysInit */
//	FlashWriteBuff( DEVICE_INFO_ADDRESS, FlashTest,sizeof(FlashTest) );        // дɫ˽ߝսFlash
//	
//	for(i=0;i<8;i++)
//    FlashWBuff[i] = 8-i;
//	
//    FlashWriteBuff( DEVICE_INFO_ADDRESS + sizeof(FlashTest), FlashWBuff,8 );  // дɫ˽ߝսFlash
//    FlashReadBuff(  DEVICE_INFO_ADDRESS + sizeof(FlashTest),FlashRBuff,8  );  // ՓFlashאׁȡ˽

	
	//    uint8_t write_data[256] = {0};
    // uint8_t read_data[256] = {0};
 
    // // 写入数据
    // for (int i = 0; i < 256; i++) {
    //     write_data[i] = i;
    // }
    // W25Q16_PageProgram(0x000000, write_data, 256);
 
    // // 读取数据
    // W25Q16_ReadData(0x000000, read_data, 256);
	

  //uint8_t aa = sizeof(TimeTableNode);
    taskENTER_CRITICAL();
    if(count%2==1)
    {
    
	   strcpy(deviceinfo.deviceSN, "ZZ233AA456789012345678");
       deviceinfo.deviceType = 0x00FC;
       deviceinfo.motorDirection[2] = 0x02;
       W25Q16_PageWrite( (uint8_t *)&deviceinfo,Storage_Device_Info_Sector,sizeof(DEVICE_INFO));
	   printf("has been write!!!\n");
       uint8_t aa =  sizeof(DEVICE_INFO);
       uint8_t bb =  sizeof(FeedStrategy);
       uint8_t cc =  sizeof(WaterMarkSensorConfigInfo);
       uint8_t dd =  sizeof(StaticDataInfo);
       uint8_t ee =  sizeof(AlarmConfigInfo);
       
        printf("aa:%d,bb:%d,cc:%d,dd:%d,ee:%d\n",aa,bb,cc,dd,ee);
    }
    else
    {
        W25Q16_Read((uint8_t *)&deviceinfo_read,Storage_Device_Info_Sector, sizeof(DEVICE_INFO));
    // 打印读取到的数据
        printf("deviceSN:%s,deviceType:%d,motorDirection[2]:%d\n",deviceinfo_read.deviceSN,deviceinfo_read.deviceType,deviceinfo_read.motorDirection[2]);

    }

    taskEXIT_CRITICAL();
   
}


void outPutPWM(void)
{
    switch (rxBuffer[1])
    {
    case 1:
        motorSpeedControl1Action = rxBuffer[2];
        TIM1_PWM_SetFrequencyAndDutyCycle(16000,motorSpeedControl1Action);
        break;
    case 2:
        motorSpeedControl2Action = rxBuffer[2];
        TIM2_PWM_SetFrequencyAndDutyCycle(16000,motorSpeedControl2Action);
        break;
    case 3:
        motorSpeedControl3Action = rxBuffer[2];
        TIM4_PWM_SetFrequencyAndDutyCycle(16000,motorSpeedControl3Action);
        break;  
    default:
        break;
    }

}


void takeTask(void)
{
                // 尝试获取信号量，防止多次触发
    if (xSemaphoreTake(triggerSemaphore, portMAX_DELAY) == pdTRUE) {
        if (dynamicTaskHandle == NULL) {
            printf("Triggering dynamic task.\n");
            uint32_t ade = 10;
            // 创建动态任务
            xTaskCreate(taskTimerMotorControl, "taskTimerMotorControl", 128,&ade, osPriorityNormal, &dynamicTaskHandle);
        }
    }
}

void getRTCTime(void)
{
    uint8_t data[UART_SEND_MAX] = {0};
    memset(data,0,UART_SEND_MAX);
		//DS1307_GetTime(&now_time.second, &now_time.minute, &now_time.hour, &now_time.date, &now_time.month, &now_time.year, &now_time.day);
    data[0] = 0x05;
    data[1] = now_time.year;
    data[2] = now_time.month;
    data[3] = now_time.date;
    data[4] = now_time.hour;
    data[5] = now_time.minute;
    data[6] = now_time.second;
    data[7] = now_time.day;
    HAL_UART_Transmit(&huart4, data, UART_SEND_MAX, HAL_MAX_DELAY);
}

void getRelayStatus(void)
{
    uint8_t data[UART_SEND_MAX] = {0};
    memset(data,0,UART_SEND_MAX);
    data[0] = 0x04;
    data[1] = motorControl1Action;
    data[2] = motorSpeedControl1Action;
    data[3] = motorDirectionControl1Action;
    data[4] = motorControl2Action;
    data[5] = motorSpeedControl2Action;
    data[6] = motorDirectionControl2Action;
    data[7] = motorControl3Action;
    data[8] = motorSpeedControl3Action;
    data[9] = motorDirectionControl3Action;
    HAL_UART_Transmit(&huart4, data, UART_SEND_MAX, HAL_MAX_DELAY);
}

void controlTask(void)
{
	   uint32_t hz,hz2,hz3;
    switch (rxBuffer[1])
    {
    case 1:
        /* code */
        flagMotorControl1Update = 1;
        if(rxBuffer[2] > 0)
        {

           if(rxBuffer[2] == 1)
           {
             motorControl1Action = 1;
             motorDirectionControl1Action = 1;
           }
           else if(rxBuffer[2] == 2)
           {
             motorControl1Action = 1;
             motorDirectionControl1Action = 0;
           }
           else
           {
             motorControl1Action = 0;
             motorDirectionControl1Action = 0;
           }
        }
        else
        {
            motorControl1Action = 0;
             motorDirectionControl1Action = 0;
        }

		hz = ((uint32_t)rxBuffer[4] * 1000);
		printf("cycle:%d, zhankongbi:%d",hz,rxBuffer[3]);
        motorSpeedControl1Action = rxBuffer[3];
        TIM1_PWM_SetFrequencyAndDutyCycle(16000,motorSpeedControl1Action);
        break;
    case 2:
        /* code */
        flagMotorControl2Update = 1;
        if(rxBuffer[2] > 0)
        {

           if(rxBuffer[2] == 1)
           {
             motorControl2Action = 1;
             motorDirectionControl2Action = 1;
           }
           else if(rxBuffer[2] == 2)
           {
             motorControl2Action = 1;
             motorDirectionControl2Action = 0;
           }
           else
           {
             motorControl2Action = 0;
             motorDirectionControl2Action = 0;
           }
        }
        else
        {
            motorControl2Action = 0;
             motorDirectionControl2Action = 0;
        }

        hz2 = ((uint32_t)rxBuffer[4] * 1000);
        printf("cycle:%d, zhankongbi:%d",hz2,rxBuffer[3]);
        motorSpeedControl2Action = rxBuffer[3];
        TIM2_PWM_SetFrequencyAndDutyCycle(16000,motorSpeedControl2Action);
        break;
    case 3:
        /* code */
        flagMotorControl3Update = 1;
        if(rxBuffer[2] > 0)
        {

           if(rxBuffer[2] == 1)
           {
             motorControl3Action = 1;
             motorDirectionControl3Action = 1;
           }
           else if(rxBuffer[2] == 2)
           {
             motorControl3Action = 1;
             motorDirectionControl3Action = 0;
           }
           else
           {
             motorControl3Action = 0;
             motorDirectionControl3Action = 0;
           }
        }
        else
        {
            motorControl3Action = 0;
             motorDirectionControl3Action = 0;
        }
		hz3 = ((uint32_t)rxBuffer[4] * 1000);
		printf("cycle:%d, zhankongbi:%d",hz3,rxBuffer[3]);
        motorSpeedControl3Action = rxBuffer[3];
        TIM4_PWM_SetFrequencyAndDutyCycle(16000,motorSpeedControl3Action);
        break;    
    default:
        break;
    }
}


void setRelayDirection(void)
{
    switch (rxBuffer[1])
    {
    case 1:
        /* code */
        flagMotorControl1Update = 1;
        motorDirectionControl1Action = rxBuffer[2];
        break;
    case 2:
        /* code */
        flagMotorControl2Update = 1;
        motorDirectionControl2Action = rxBuffer[2];
        break;
    case 3:
        /* code */
        flagMotorControl3Update = 1;
        motorDirectionControl3Action = rxBuffer[2];
        break;    
    default:
        break;
    }
}

void eraseAll(void)
{
    W25Q16_ChipErase();
}


void setParamByMqtt(void)
{
 	 if(isCRCLegal() != pdPASS)
	 {
			 printf("CRC is illegal\n");
			 return;
	 }
	
    QueueSetParamEvent e;
    if (taskStorageQueue != NULL) {
          e.event = 2;
          e.len = rxIndex;
          memcpy(&e.data, rxBuffer, rxIndex);
         xQueueSend(taskStorageQueue, &e,0); // 初始状态为可触发 触发存储任务
    }
}

void sendByMqtt(uint8_t cmd)
{ 
    //FeedStrategy
    uint8_t data[UART_SEND_MAX] = {0};
    memset(data,0,UART_SEND_MAX);
    data[0] = 0x07;
    data[1] = cmd;

    if(cmd >= 0x12 && cmd <= 0x19)
    {
        memcpy(&data[2], &feedStrategy, sizeof(FeedStrategy));
    }
    else if(cmd == 0x1A)
    {
        data[2] = motorControl1Action;
        data[3] = motorSpeedControl1Action;
        data[4] = motorDirectionControl1Action;
        data[5] = motorControl2Action;
        data[6] = motorSpeedControl2Action;
        data[7] = motorDirectionControl2Action;
        data[8] = motorControl3Action;
        data[9] = motorSpeedControl3Action;
        data[10] = motorDirectionControl3Action;
    }
    else if(cmd == 0x1B)
    {
        memcpy(&data[2], SOFTWARE_VERSION, 33);
    }

    HAL_UART_Transmit(&huart4, data, UART_SEND_MAX, HAL_MAX_DELAY);
}
